/**
 * 段落类
 */
var Paragraph = function(ctx, left, top, imageData, cursor) {
    this.ctx = ctx;
    this.drawimgSurface = imageData;
    this.left = left;
    this.top = top;
    this.lines = [];
    this.activeLine = undefined;
    this.cursor = cursor;
    this.blinkingInterval = undefined;
}
//原型···············
Paragraph.prototype = {
    //给定点是否在范围内
    isPointInside: function(loc) {
        var c = this.ctx;
        ctx.beginPath();
        ctx.rect(this.left, this.top, this.getWidth(), this.getHeight());
        return c.isPointInPath(loc.x, loc.y);
    },
    //获取段落高度，为内部所有行高之和
    getHeight: function() {
        var h = 0;
        this.lines.forEach( function (line) {
            h += line.getHeight(this.ctx);
        });
        return h;
    },
    //获取段落宽度，为所有行最宽的一个
    getWidth: function () {
        var w = 0, widest = 0;
        this.lines.forEach( function (line) {
            w = line.getWidth(this.ctx);
            if(w > widest) {
                widest = w;
            }
        });
        return widest;
    },
    //绘制段落，即绘制所有行
    draw: function() {
        this.lines.forEach( function (line) {
            line.darw(this.ctx);
        })
    },
    //擦除段落
    erase: function (ctx, imageData) {
        ctx.putImageData(imageData, 0, 0);
    },
    //换行
    addLine: function(line) {
        this.lines.push(line);
        this.activeLine = line;
        this.moveCursor(line.left, line.bottom); //移动光标到新行
    },
    //插入文本
    insert: function(text) {
        this.erase(this.ctx, this.drawimgSurface); //先擦除全部原有文本
        this.activeLine.insert(text);
        var t = this.activeLine.text.substring(0, this.activeLine.caret);
        var w = this.ctx.measureText(t).width;
        this.moveCursor(this.activeLine.left + w, this.activeLine.bottom);
        this.draw(this.ctx);
    },
    //光标闪烁效果
    blinkCursor: function (x, y) {
        var self = this,
            BLINK_OUT = 200,
            BLINK_INTERVAL = 900;
        this.blinkingInterval = setInterval( function () {
            this.cursor.erase(this.ctx, this.drawimgSurface);
            setTimeout( function () {
                this.cursor.darw(ctx, this.cursor.left, this.cursor.top + this.cursor.getHeight(ctx) / 2);
            }, BLINK_OUT);
        }, BLINK_INTERVAL);
    },
    //将光标移动到指定行指定列
    moveCursorCloseTo: function (x, y) {
        var line = this.getLine(y);
        if(line) {
            line.caret = this.getColumn(line, x);
            this.activeLine = line;
            this.moveCursor(line.getCaretX(ctx), line.bottom);
        }
    },
    //移动光标
    moveCursor: function(x, y) {
        this.cursor.erase(this.ctx, this.drawimgSurface);
        this.cursor.draw(this.ctx, x, y);
        if(!this.blinkingInterval) {
            this.blinkCursor(x, y);
        }
    },
    moveLineDown: function (start) {
        var line;
        for(var i = start; i < this.lines.length; i++) {
            line = this.lines[i];
            line.bottom += line.getHeight(this.ctx);
        }
    },
    newline: function () {
        var textBeforeCursor = this.activeLine.text.substring(0, this.activeLine.caret),
            textAfterCursor = this.activeLine.text.substring(this.activeLine.caret),
            height = this.ctx.measureText('W').width + this.ctx.measureText('W').width / 6
            bottom = this.activeLine.bottom + height,
            activeIndex, line;
        
        this.erase(this.ctx, this.drawimgSurface);
        this.activeLine.text = textBeforeCursor;

        line = new TextLine(this.activeLine.line, bottom);
        line.insert(textAfterCursor);

        activeIndex = this.lines.indexOf(this.activeLine);
        this.lines.splice(activeIndex + 1, 0, line);

        this.activeLine = line;
        this.activeLine.caret = 0;

        activeIndex = this.lines.indexOf(this.activeLine);

        for(var i = activeIndex + 1; i <this.lines.length; i++) {
            line = this.lines[i];
            line.bottom += height;
        }

        this.darw();
        this.cursor.draw(this.ctx, this.activeLine.left, this.activeLine.bottom);
    },
    getLine: function(y) {
        var line;
        for(var i = 0; i < this.lines.length; i += 1) {
            line = this.ines[i];
            if(y > line.bottom - line.getHeight(ctx) && y < line.bottom) {
                return line;
            }
        }
        return undefined;
    },
    //获取当前光标所在列数
    getColumn: function(line, x) {
        var found = false,
            before, after, closest, tmpLine, column;
        tmpLine = new TextLine(line.left, line.bottom);
        tmpLine.insert(line.text);

        while( !found && tmpLine.text.length > 0) {
            before = tmpLine.left + tmpLine.getWidth(this.ctx);
            tmpLine.removeLastCharacter();
            after = tmpLine.left + tmpLine.getWidth(this.ctx);

            if(after < x) {
                closest = x - after < before - x ? after : before;
                column = closest === before ? tmpLine.text.length + 1 : tmpLine.text.length;
                found = true;
            }
        }
        return column;
    },
    activeLineIsOutOfText: function () {
        return this.activeLineIsOutOfText.text.length === 0;
    },
    activeLineIsTopLine: function () {
        return this.lines[0] === this.activeLine;
    },
    moveUpOneLine: function () {
        var lastActiveText, line, before, after;

        lastActiveLine = this.activeLine;
        lastActiveText = '' + lastActiveLine.text;

        activeIndex = this.lines.indexOf(this.activeLine);
        this.activeLine = this.lines[activeIndex - 1];
        this.activeLine.caret = this.activeLine.text.length;

        this.ines.splice(activeIndex, 1);

        this.moveCursor(
            this.activeLine.left + this.activeLine.getWidth(this.ctx),
            this.activeLine.bottom
        );

        this.activeLine.text += lastActiveText;

        for(var i = activeIndex; i < this.lines.length; ++i) {
            line = this.lines[i];
            line.bottom -= line.getHeight(this.ctx);
        }
    },
    backspace: function() {
        var lastActiveLine,
            activeIndex, t, w;
        
        this.ctx.save();

        if(this.activeLine.caret === 0) {
            if(!this.activeLineIsTopLine()) {
                this.erase(this.ctx, this.drawimgSurface);
                this.moveUpOneLine();
                this.draw();
            }
        } else {
            this.ctx.fillStyle = '#00bbff';
            this.ctx.strokeStyle = '#000';
            this.erase(this.ctx, this.drawimgSurface);
            this.activeLine.removeLastCharacter();

            t = this.activeLine.text.slice(0, this.activeLine.caret);
            w = this.ctx.measureText(t).width;

            this.moveCursor(this.activeLine.left + w, this.activeLine.bottom);

            this.draw(this.ctx);
            this.ctx.restore();
        }
    }
}